//REQUIRED CLASS
package project4;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.TreeSet;

import javax.swing.text.html.HTMLDocument.Iterator;

import project1.*;
import project2.*;

public final class Relation
{
	private final String schemaname;
	private final ArrayList<String> schema;
	public Tuple tuple;
	
	public Relation(String SchemaName,ArrayList<String> attrList){
		this.schemaname = SchemaName;
		this.schema = attrList;
		this.tuple = new Tuple();
	}
	
	public String getSchemeName(){
		return this.schemaname;
	}
	public ArrayList<String> getSchema(){
		return this.schema;
	}
	public Relation select(String variable, String value){
		Relation newrelation = new Relation(this.getSchemeName(),this.schema);
		//Goes through current relation and return a relation with only those tuples that make the criteria
		for(TupleHashMap hm : this.tuple){
			if(value.equals(hm.get(variable))){
				newrelation.tuple.add(hm);
			}
		}
		return newrelation;
	}
	public Relation rename(ArrayList<String> newschema){
		Relation newrelation = new Relation(this.getSchemeName(),newschema);
		//Loop through list
		for(HashMap<String, String> currentHashMap : this.tuple){
			int i=0;
			TupleHashMap temphashmap = new TupleHashMap(newschema);
			//Each Hashmap add to new temphashmap with new names
			for(String argCurrentScheme : this.schema){
				if(temphashmap.get(newschema.get(i)) == null) 
					temphashmap.put(newschema.get(i), currentHashMap.get(argCurrentScheme));
				//If there is a duplicate name and the values are not the same
				else if (!temphashmap.get(newschema.get(i)).equals(currentHashMap.get(argCurrentScheme))){
					temphashmap = null;
					break;
				}
				i++;
			}
			if(temphashmap!=null)
				newrelation.tuple.add(temphashmap);
		}
		return newrelation;
	}
	/*
	 * Returns the string of the relation
	 * @see java.lang.Object#toString()
	 */
	public String toString(){
		String toString="";
		int i = 0;
		for(HashMap variableValues : new TreeSet<HashMap>(this.tuple)){
			HashMap seen = new HashMap();
			boolean added = false;
			String[] tempString= new String[20];
			int j = 0;
			for(String variableSchema : this.schema){
				if(Database.freeVariables.get(variableSchema)!=null){
					if(seen.get(variableSchema)!=null)
						continue;
					seen.put(variableSchema, 1);
					tempString[j] = variableSchema+"="+(String) variableValues.get(variableSchema);
					//toString+=variableSchema+"="+(String) variableValues.get(variableSchema);
					added = true; //Needed to know if a \n is needed
					j++;
				}
				
			}
			i++;
			//System.out.println(combine(tempString,", "));
			if (added )
				toString+="  "+combine(tempString,", ")+"\n";
			
		}
		return toString;
	}
	private boolean checkIfString(String queryString){
		 return queryString.matches("\'.*\'");
	}
	private String combine(String[] s, String glue)
	{
	  
	  int k=s.length;
	  if (k==0)
	    return null;
	  StringBuilder out=new StringBuilder();
	  out.append(s[0]);
	  for (int x=1;x<k;++x){
		  if (s[x]!=null)
			  out.append(glue).append(s[x]);
	  }
	  return out.toString();
	}
}
